package com.ls.fw.mvc.springmvc.base;

import java.beans.PropertyEditorSupport;
import java.util.Collection;
import java.util.Date;
import java.util.List;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang3.StringEscapeUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.ui.Model;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.context.request.WebRequest;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import com.ls.fw.commons.core.utils.date.DateUtils;
import com.ls.fw.data.bean.PageBean;
import com.ls.fw.data.bean.ResultStatus;
import com.ls.fw.data.bean.ResultTemplate;
import com.ls.fw.mvc.springmvc.constant.Global;
import com.ls.fw.mvc.springmvc.util.ViewUtil;
import com.ls.fw.web.core.bean.FwHttpConstant;
import com.ls.fw.web.core.servlet.utils.HttpUtils;

/**
 * 
 * 
 * @author lisheng
 * @date 2015年6月27日 下午3:59:42
 * @version V1.0
 */
public abstract class BaseSimpleController{

	protected Logger logger = LoggerFactory.getLogger(getClass());
	public static final String JSON_FLAG = FwHttpConstant.JSON_FLAG;
	public static final String CALLBACK_PARA =  FwHttpConstant.CALLBACK_PARA;
 
	/**
	 * 初始化数据绑定
	 * 1. 将所有传递进来的String进行HTML编码，防止XSS攻击
	 * 2. 将字段中Date类型转换为String类型
	 */
	@InitBinder
	protected void initBinder(WebDataBinder binder) {
		// prevent xss attack
//		binder.registerCustomEditor(String.class, new StringEscapeEditor(true, false));
	
		// String类型转换，将所有传递进来的String进行HTML编码，防止XSS攻击
		binder.registerCustomEditor(String.class, new PropertyEditorSupport() {
			@Override
			public void setAsText(String text) {
				setValue(text == null ? null : StringEscapeUtils.escapeHtml4(text.trim()));
			}
			@Override
			public String getAsText() {
				Object value = getValue();
				return value != null ? value.toString() : "";
			}
		});
		// Date 类型转换
		binder.registerCustomEditor(Date.class, new PropertyEditorSupport() {
			@Override
			public void setAsText(String text) {
				setValue(DateUtils.parseDate(text));
			}
//			@Override
//			public String getAsText() {
//				Object value = getValue();
//				return value != null ? DateUtils.formatDateTime((Date)value) : "";
//			}
		});
	}
	 
	/**
	 * 添加Model消息
	 * @param messages 消息
	 */
	protected void addMessage(Model model, String... messages) {
		StringBuilder sb = new StringBuilder();
		for (String message : messages){
			sb.append(message).append(messages.length>1?"<br/>":"");
		}
		model.addAttribute(Global.MSG, sb.toString());
	}
	
	/**
	 * 添加Flash消息
     * @param messages 消息
	 */
	protected void addMessage(RedirectAttributes redirectAttributes, String... messages) {
		StringBuilder sb = new StringBuilder();
		for (String message : messages){
			sb.append(message).append(messages.length>1?"<br/>":"");
		}
		redirectAttributes.addFlashAttribute(Global.MSG, sb.toString());
	}

    /**
     * 默认页面路径前缀
     * @return
     */
    protected String defaultViewPrefix() {
        String currentViewPrefix = "";
        RequestMapping requestMapping = AnnotationUtils.findAnnotation(getClass(), RequestMapping.class);
        if (requestMapping != null && requestMapping.value().length > 0) {
            currentViewPrefix = requestMapping.value()[0];
        }
//        if (StringUtils.isEmpty(currentViewPrefix)) {
//            currentViewPrefix = this.entityClass.getSimpleName();
//        }
        return currentViewPrefix;
    }
     
	
    /**
     * 设置通用数据
     *
     * @param model
     */
    protected void setCommonData(Model model) {
    }

    
    /**
     * 封装结果
     * 
     * @author lisheng
     * @date 2015年9月9日 下午10:41:46
     * @version V1.0
     * @param mav
     * @param resultTemplate
     * @return
     */
    protected ModelAndView returnResult(ModelAndView mav,ResultTemplate resultTemplate){
		mav.addAllObjects(resultTemplate.getValidObj());
		return mav;
    }
    

    /**
     * 封装结果
     * 
     * @author lisheng
     * @date 2015年9月9日 下午10:43:17
     * @version V1.0
     * @param resultTemplate
     * @param viewName
     * @return
     */
    protected ModelAndView returnResult(ResultTemplate resultTemplate,String viewName){
    	ModelAndView mav = new ModelAndView(viewName);
		return this.returnResult(mav, resultTemplate);
    }
    protected ModelAndView returnResult(ResultTemplate resultTemplate){
    	ModelAndView mav = new ModelAndView();
		return this.returnResult(mav, resultTemplate);
    }
    /**
     * 封装结果
     * 
     * @author lisheng
     * @date 2015年9月9日 下午10:41:31
     * @version V1.0
     * @param m
     * @param resultTemplate
     * @return
     */
    protected Model returnResult(Model m,ResultTemplate resultTemplate){
		m.addAllAttributes(resultTemplate.getValidObj());
		return m;
    }
    

    /**
     * 转换数据
     * @author lisheng
     * @date 2016年6月13日 下午8:21:42
     * @version V1.0
     * @param result
     * @param style
     * @param list
     * @return
     */
    protected Object toData(ResultTemplate result,String style,Collection list){
    	PageBean p = new PageBean(list);
    	Object obj = p;
    	if(PageBean.BS_GRID.equals(style)){
    		obj = p.toBsGridPageInfo();
    		result.setOnlyData(true);
    	}else if(PageBean.JQ_GRID.equals(style)){
    		obj = p.toJqGridPageInfo();
    		result.setOnlyData(true);
    	}else if(PageBean.EASYUI_GRID.equals(style)){
    		obj = p.toEasyUiGridPageInfo();
    		result.setOnlyData(true);
    	}else if(PageBean.DATATABLE_GRID.equals(style)){
    		obj = p.toDataTablePageInfo();
    		result.setOnlyData(true);
    	}
    	return obj;
    }
    
    
    @RequestMapping("/ping") 
    public ModelAndView ping(HttpServletRequest req) {
        ModelAndView mavAndView = new ModelAndView("");
        ResultTemplate t = ResultTemplate.newInstance();
        t.setStatus(ResultStatus.OK.status());
        mavAndView.addAllObjects(t);
        return ViewUtil.convert(mavAndView, req, true, false,null);
    }  	
     
    @RequestMapping("/view/{name}")
    public ModelAndView index(HttpServletRequest req, @PathVariable(value = "name") String name) {
        ModelAndView mavAndView = new ModelAndView(this.defaultViewPrefix()+"/"+name);
        mavAndView.addAllObjects(HttpUtils.getAllPara(req,false));
        return mavAndView;
    }  
    protected <Q>  ModelAndView execute(Q model, WebRequest webRequest
			, String viewName, DefaultWorkHandler<Q> mapper) throws Exception{
		ResultTemplate obj = mapper.doWork(model,webRequest);
		return ViewUtil.convert(this.returnResult(obj, viewName)
				, webRequest,obj.isForceJson());
	}
    public interface WorkHandler{
	}
    public interface DefaultWorkHandler<T> extends WorkHandler{
		
		/**
		 * 执行工作
		 * 
		 * @author lisheng
		 * @date 2015年10月1日 下午3:05:00
		 * @version V1.0
		 * @param model
		 * @param webRequest
		 * @return
		 * @throws Exception
		 */
		ResultTemplate doWork(T model, WebRequest webRequest) throws Exception;
		
		
    }
}





